package com.lcy.web.generator;

import com.lcy.web.Const;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

/**
 * Created by loucunyin on 2017/1/4 0004.
 * 生成建表 sql , 将 sql 导入数据库
 * 依赖于系统命令，需要将 mysql 加入到环境变量中
 */
public class SqlFileGenerator {
    private static final String EXPORT_SQL = "mysqldump -u%s -p%s %s > %s";
    private static final String IMPORT_SQL = "mysql -u%s -p%s %s < %s";
    private static final String[] LINUX_CMD = {"sh", "-c", null};
    private static final String[] WINDOWS_CMD = {"cmd.exe", "/C", null};
    private static final String WIN = "Win";
    private static final String LINUX = "Linux";

    private static final int TYPE_WIN = 1;
    private static final int TYPE_LINUX = 2;

    private static String sCharSet = "utf-8";

    public static void main(String[] args) {
        // 导出 sql 文件
        exportSql(null);
    }

    /**
     * 使用默认属性导出数据库
     */
    public static void exportSql(String moduleName){
        String userName = Const.getDbUser();
        String password = Const.getDbPassword();
        String dbName = Const.getDbName();
        String filePath = getExportSqlFilePath(moduleName);
        exportSql(userName,password,dbName,filePath);
    }

    /**
     * 导出数据库
     * @param userName 用户名
     * @param password 密码
     * @param databaseName 数据库名
     * @param filePath 导出文件的路径
     */
    public static void exportSql(String userName, String password, String databaseName, String filePath) {
        String cmd = String.format(EXPORT_SQL, userName, password, databaseName, filePath);
        System.out.println(cmd);
        execSystemCmd(cmd);
    }

    /**
     * 导入数据库
     */
    public static void importSql(){
        String userName = Const.getDbUser();
        String password = Const.getDbPassword();
        String dbName = Const.getDbName();
        String filePath = getSqlFilePath();
        if(filePath == null){
            return;
        }
        importSql(userName,password,dbName,filePath);
    }

    /**
     * 导入数据库
     * @param userName 用户名
     * @param password 密码
     * @param databaseName 数据库名
     * @param filePath 导出文件的路径
     */
    public static void importSql(String userName, String password, String databaseName, String filePath) {
        String cmd = String.format(IMPORT_SQL, userName, password, databaseName, filePath);
        System.out.println(cmd);
        execSystemCmd(cmd);
    }


    /**
     * 执行 cmd 或者 bash 命令
     * @param cmd cmd
     */
    public static void exec(String... cmd) {
        try {
            Process ps = Runtime.getRuntime().exec(cmd);
            System.out.println(loadStream(ps.getInputStream()));
            System.err.println(loadStream(ps.getErrorStream()));
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

    /**
     * 执行操作系统命令
     * @param cmd cmd
     */
    public static void execSystemCmd(String cmd) {
        String osName = getOsName();
        String[] cmds = null;
        switch (getOsType()) {
            case TYPE_LINUX:
                cmds = LINUX_CMD;
                break;
            case TYPE_WIN:
                cmds = WINDOWS_CMD;
                sCharSet = "gbk";
                break;
            default:
                return;
        }

        cmds[2] = cmd;
        exec(cmds);
    }


    private static String loadStream(InputStream in) throws IOException {
        int len = 0;
        in = new BufferedInputStream(in);
        byte[] bytes = new byte[1024];

        StringBuilder buffer = new StringBuilder();
        while ((len = in.read(bytes)) != -1) {
            buffer.append(new String(bytes, sCharSet));
        }
        return buffer.toString();
    }

    private static String getSqlFilePath() {
        String template = "res/sql/%s.sql";
        URL url = SqlFileGenerator.class.getClassLoader().getResource(String.format(template,Const.getDbName()));
        if(url == null){
            return null;
        }
        String filePath = url.getPath();
        if (getOsType() == TYPE_WIN){
            filePath = filePath.substring(1);
            filePath = filePath.replace("/", File.separator);
        }
        return filePath;
    }

    private static String getExportSqlFilePath(String moduleName){
        String projectPath = System.getProperty("user.dir");
        String packageName = "src.main.resources.res.sql."+Const.getDbName();
        if(moduleName != null){
            packageName = moduleName + "." + packageName;
        }
        packageName = packageName.replace(".",File.separator);
        return projectPath + File.separator + packageName +".sql";
    }

    private static String getOsName() {
        return System.getProperties().getProperty("os.name");
    }

    private static int getOsType() {
        int type = 0;
        String osName = getOsName();
        if (osName.contains(WIN)) {
            return TYPE_WIN;
        } else if (osName.contains(LINUX)) {
            return TYPE_LINUX;
        }
        return type;
    }
}
